{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "from tensorflow.python.keras.utils import get_file\n",
    "import gzip\n",
    "import numpy as np\n",
    "import keras\n",
    "from keras.preprocessing.image import ImageDataGenerator\n",
    "from keras.models import Sequential\n",
    "from keras.layers import Dense, Dropout, Activation, Flatten\n",
    "from keras.layers import Conv2D, MaxPooling2D\n",
    "import os\n",
    "import functools\n",
    "# os.environ[\"CUDA_VISIBLE_DEVICES\"] = \"2\"  # 使用第3块显卡"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 读取数据与数据预处理"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 数据集和代码放一起即可\n",
    "def load_data():\n",
    "    paths = [\n",
    "        'train-labels-idx1-ubyte.gz', 'train-images-idx3-ubyte.gz',\n",
    "        't10k-labels-idx1-ubyte.gz', 't10k-images-idx3-ubyte.gz'\n",
    "    ]\n",
    "\n",
    "    with gzip.open(paths[0], 'rb') as lbpath:\n",
    "        y_train = np.frombuffer(lbpath.read(), np.uint8, offset=8)\n",
    "\n",
    "    with gzip.open(paths[1], 'rb') as imgpath:\n",
    "        x_train = np.frombuffer(\n",
    "            imgpath.read(), np.uint8, offset=16).reshape(len(y_train), 28, 28, 1)\n",
    "\n",
    "    with gzip.open(paths[2], 'rb') as lbpath:\n",
    "        y_test = np.frombuffer(lbpath.read(), np.uint8, offset=8)\n",
    "\n",
    "    with gzip.open(paths[3], 'rb') as imgpath:\n",
    "        x_test = np.frombuffer(\n",
    "            imgpath.read(), np.uint8, offset=16).reshape(len(y_test), 28, 28, 1)\n",
    "    return (x_train, y_train), (x_test, y_test)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "(x_train, y_train), (x_test, y_test) = load_data()\n",
    "batch_size = 32\n",
    "num_classes = 10\n",
    "epochs = 5\n",
    "data_augmentation = True  # 图像增强\n",
    "num_predictions = 20\n",
    "save_dir = os.path.join(os.getcwd(), 'saved_models_cnn')\n",
    "model_name = 'keras_fashion_trained_model.h5'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Convert class vectors to binary class matrices. 类别独热编码\n",
    "y_train = keras.utils.to_categorical(y_train, num_classes)\n",
    "y_test = keras.utils.to_categorical(y_test, num_classes)\n",
    "\n",
    "\n",
    "x_train = x_train.astype('float32')\n",
    "x_test = x_test.astype('float32')\n",
    "\n",
    "x_train /= 255  # 归一化\n",
    "x_test /= 255  # 归一化"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 搭建传统CNN模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "model = Sequential()\n",
    "model.add(Conv2D(32, (3, 3), padding='same',  # 32，(3,3)是卷积核数量和大小\n",
    "                 input_shape=x_train.shape[1:]))  # 第一层需要指出图像的大小\n",
    "model.add(Activation('relu'))\n",
    "model.add(Conv2D(32, (3, 3)))\n",
    "model.add(Activation('relu'))\n",
    "model.add(MaxPooling2D(pool_size=(2, 2)))\n",
    "model.add(Dropout(0.25))\n",
    "\n",
    "model.add(Conv2D(64, (3, 3), padding='same'))\n",
    "model.add(Activation('relu'))\n",
    "model.add(Conv2D(64, (3, 3)))\n",
    "model.add(Activation('relu'))\n",
    "model.add(MaxPooling2D(pool_size=(2, 2)))\n",
    "model.add(Dropout(0.25))\n",
    "\n",
    "model.add(Flatten())\n",
    "model.add(Dense(512))\n",
    "model.add(Activation('relu'))\n",
    "model.add(Dropout(0.5))\n",
    "model.add(Dense(num_classes))\n",
    "model.add(Activation('softmax'))\n",
    "\n",
    "# initiate RMSprop optimizer\n",
    "opt = keras.optimizers.rmsprop(lr=0.0001, decay=1e-6)\n",
    "\n",
    "# Let's train the model using RMSprop\n",
    "model.compile(loss='categorical_crossentropy',\n",
    "              optimizer=opt,\n",
    "              metrics=['accuracy'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 训练"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Using real-time data augmentation.\n",
      "1875\n",
      "1875.0\n",
      "Epoch 1/5\n",
      "1875/1875 [==============================] - 187s 100ms/step - loss: 0.9836 - acc: 0.6374 - val_loss: 0.6204 - val_acc: 0.7603\n",
      "Epoch 2/5\n",
      "1875/1875 [==============================] - 186s 99ms/step - loss: 0.6752 - acc: 0.7419 - val_loss: 0.5404 - val_acc: 0.7965\n",
      "Epoch 3/5\n",
      "1875/1875 [==============================] - 205s 109ms/step - loss: 0.5921 - acc: 0.7764 - val_loss: 0.4921 - val_acc: 0.8159\n",
      "Epoch 4/5\n",
      "1875/1875 [==============================] - 193s 103ms/step - loss: 0.5368 - acc: 0.8000 - val_loss: 0.4262 - val_acc: 0.8440\n",
      "Epoch 5/5\n",
      "1875/1875 [==============================] - 194s 104ms/step - loss: 0.4958 - acc: 0.8145 - val_loss: 0.4366 - val_acc: 0.8448\n"
     ]
    }
   ],
   "source": [
    "if not data_augmentation:\n",
    "    print('Not using data augmentation.')\n",
    "    history = model.fit(x_train, y_train,\n",
    "              batch_size=batch_size,\n",
    "              epochs=epochs,\n",
    "              validation_data=(x_test, y_test),\n",
    "              shuffle=True)\n",
    "else:\n",
    "    print('Using real-time data augmentation.')\n",
    "    # This will do preprocessing and realtime data augmentation:\n",
    "    datagen = ImageDataGenerator(\n",
    "        featurewise_center=False,  # set input mean to 0 over the dataset\n",
    "        samplewise_center=False,  # set each sample mean to 0\n",
    "        featurewise_std_normalization=False,  # divide inputs by std of the dataset\n",
    "        samplewise_std_normalization=False,  # divide each input by its std\n",
    "        zca_whitening=False,  # apply ZCA whitening\n",
    "        zca_epsilon=1e-06,  # epsilon for ZCA whitening\n",
    "        rotation_range=0,  # randomly rotate images in the range (degrees, 0 to 180)\n",
    "        # randomly shift images horizontally (fraction of total width)\n",
    "        width_shift_range=0.1,\n",
    "        # randomly shift images vertically (fraction of total height)\n",
    "        height_shift_range=0.1,\n",
    "        shear_range=0.,  # set range for random shear\n",
    "        zoom_range=0.,  # set range for random zoom\n",
    "        channel_shift_range=0.,  # set range for random channel shifts\n",
    "        # set mode for filling points outside the input boundaries\n",
    "        fill_mode='nearest',\n",
    "        cval=0.,  # value used for fill_mode = \"constant\"\n",
    "        horizontal_flip=True,  # randomly flip images\n",
    "        vertical_flip=False,  # randomly flip images\n",
    "        # set rescaling factor (applied before any other transformation)\n",
    "        rescale=None,\n",
    "        # set function that will be applied on each input\n",
    "        preprocessing_function=None,\n",
    "        # image data format, either \"channels_first\" or \"channels_last\"\n",
    "        data_format=None,\n",
    "        # fraction of images reserved for validation (strictly between 0 and 1)\n",
    "        validation_split=0.0)\n",
    "\n",
    "    # Compute quantities required for feature-wise normalization\n",
    "    # (std, mean, and principal components if ZCA whitening is applied).\n",
    "    datagen.fit(x_train)\n",
    "    print(x_train.shape[0]//batch_size)  # 取整\n",
    "    print(x_train.shape[0]/batch_size)  # 保留小数\n",
    "    # Fit the model on the batches generated by datagen.flow().\n",
    "    history = model.fit_generator(datagen.flow(x_train, y_train,  # 按batch_size大小从x,y生成增强数据\n",
    "                                     batch_size=batch_size),  \n",
    "                        # flow_from_directory()从路径生成增强数据,和flow方法相比最大的优点在于不用\n",
    "                        # 一次将所有的数据读入内存当中,这样减小内存压力，这样不会发生OOM\n",
    "                        epochs=epochs,\n",
    "                        steps_per_epoch=x_train.shape[0]//batch_size,\n",
    "                        validation_data=(x_test, y_test),\n",
    "                        workers=10  # 在使用基于进程的线程时，最多需要启动的进程数量。\n",
    "                       )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 模型可视化与保存模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "conv2d_5 (Conv2D)            (None, 28, 28, 32)        320       \n",
      "_________________________________________________________________\n",
      "activation_7 (Activation)    (None, 28, 28, 32)        0         \n",
      "_________________________________________________________________\n",
      "conv2d_6 (Conv2D)            (None, 26, 26, 32)        9248      \n",
      "_________________________________________________________________\n",
      "activation_8 (Activation)    (None, 26, 26, 32)        0         \n",
      "_________________________________________________________________\n",
      "max_pooling2d_3 (MaxPooling2 (None, 13, 13, 32)        0         \n",
      "_________________________________________________________________\n",
      "dropout_4 (Dropout)          (None, 13, 13, 32)        0         \n",
      "_________________________________________________________________\n",
      "conv2d_7 (Conv2D)            (None, 13, 13, 64)        18496     \n",
      "_________________________________________________________________\n",
      "activation_9 (Activation)    (None, 13, 13, 64)        0         \n",
      "_________________________________________________________________\n",
      "conv2d_8 (Conv2D)            (None, 11, 11, 64)        36928     \n",
      "_________________________________________________________________\n",
      "activation_10 (Activation)   (None, 11, 11, 64)        0         \n",
      "_________________________________________________________________\n",
      "max_pooling2d_4 (MaxPooling2 (None, 5, 5, 64)          0         \n",
      "_________________________________________________________________\n",
      "dropout_5 (Dropout)          (None, 5, 5, 64)          0         \n",
      "_________________________________________________________________\n",
      "flatten_2 (Flatten)          (None, 1600)              0         \n",
      "_________________________________________________________________\n",
      "dense_3 (Dense)              (None, 512)               819712    \n",
      "_________________________________________________________________\n",
      "activation_11 (Activation)   (None, 512)               0         \n",
      "_________________________________________________________________\n",
      "dropout_6 (Dropout)          (None, 512)               0         \n",
      "_________________________________________________________________\n",
      "dense_4 (Dense)              (None, 10)                5130      \n",
      "_________________________________________________________________\n",
      "activation_12 (Activation)   (None, 10)                0         \n",
      "=================================================================\n",
      "Total params: 889,834\n",
      "Trainable params: 889,834\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n",
      "Saved trained model at /home/student/ChileWang/machine_learning_homework/question_one/saved_models_cnn/keras_fashion_trained_model.h5 \n"
     ]
    }
   ],
   "source": [
    "model.summary()\n",
    "# Save model and weights\n",
    "if not os.path.isdir(save_dir):\n",
    "    os.makedirs(save_dir)\n",
    "model_path = os.path.join(save_dir, model_name)\n",
    "model.save(model_path)\n",
    "print('Saved trained model at %s ' % model_path)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 训练过程可视化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "# 绘制训练 & 验证的准确率值\n",
    "plt.plot(history.history['acc'])\n",
    "plt.plot(history.history['val_acc'])\n",
    "plt.title('Model accuracy')\n",
    "plt.ylabel('Accuracy')\n",
    "plt.xlabel('Epoch')\n",
    "plt.legend(['Train', 'Valid'], loc='upper left')\n",
    "plt.savefig('tradition_cnn_valid_acc.png')\n",
    "plt.show()\n",
    "\n",
    "# 绘制训练 & 验证的损失值\n",
    "plt.plot(history.history['loss'])\n",
    "plt.plot(history.history['val_loss'])\n",
    "plt.title('Model loss')\n",
    "plt.ylabel('Loss')\n",
    "plt.xlabel('Epoch')\n",
    "plt.legend(['Train', 'Valid'], loc='upper left')\n",
    "plt.savefig('tradition_cnn_valid_loss.png')\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
